package show.me.the.money.service.core;

import java.util.HashMap;
import java.util.List;

import show.me.the.money.accredit.User;
import show.me.the.money.accredit.condition.Condition;
import show.me.the.money.accredit.result.AuthorizeResult;
import show.me.the.money.config.schema.Schema;
import show.me.the.money.config.schema.SchemaController;
import show.me.the.money.dictionary.Dictionaries;
import show.me.the.money.dictionary.Dictionary;
import show.me.the.money.util.ConfigValueParser;
import show.me.the.money.util.context.Context;
import show.me.the.money.util.context.HashMapContext;


public class SchemaLoader implements Service{

	public void execute(HashMap<String,Object> req,HashMap<String,Object> res,Context ctx) {
		int code = 200;
		String msg = "Success";
		
		String id = (String)req.get("id");
		Schema s = SchemaController.instance().getSchema(id);
		if(s != null){
			res.put("body", filter(s.data(),ctx));
		}
		else{
			code = 404;
			msg = "NoSuchSchema";
		}
		res.put("x-response-code", code);
		res.put("x-response-msg", msg);
	}
	@SuppressWarnings("unchecked")
	public static HashMap<String,Object> filter(HashMap<String,Object> schema,Context ctx){
		User user = (User)ctx.get("user.instance");
		String entryName =  (String)schema.get("id");
		AuthorizeResult result = user.authorize("storage",entryName);
		if(result.getResult() == AuthorizeResult.NO){
			schema.remove("items");
		}
		else{
			schema.put("acValue",result.getAuthorizeValue());
			List<HashMap<String,Object>> items = (List<HashMap<String,Object>>)schema.get("items");
			AuthorizeResult r = null;
			for(HashMap<String,Object> item :items){
				String fid = entryName + "." + item.get("id");
				r = user.authorize("storage", fid);
				if(r.getResult() > AuthorizeResult.NO){
					item.put("acValue",r.getAuthorizeValue());
					List<Condition> list = r.getAllConditions();
					if(list == null || list.size() == 0){
						parseItemAttr(item,ctx);
						continue;
					}
					Context itemCtx = new HashMapContext(item);
					ctx.putCtx("cfg", itemCtx);
					for(Condition cnd : list){
						if(cnd.type() == Condition.OVERRIDE){
							cnd.run(ctx);
						}
					}
					
				}
				else{
					item.put("acValue", "0000");
				}
				parseItemAttr(item,ctx);
			}
		}
		return schema;
	}
	
	@SuppressWarnings("unchecked")
	private static void parseItemAttr(HashMap<String,Object> item,Context ctx){
		if(item.containsKey("defaultValue")){
			Object v = ConfigValueParser.parse((String)item.get("defaultValue"),ctx);
			HashMap<String,Object> d = (HashMap<String,Object>)item.get("dic");
			if(d != null){
				String dicId = (String)d.get("id");
				Dictionary dic = Dictionaries.instance().getDic(dicId);
				HashMap<String,Object> dv = new HashMap<String,Object>();
				dv.put("key", v);
				dv.put("text",dic.getText((String)v));
				item.put("defaultValue",dv);
			}
			else{
				item.put("defaultValue",v);
			}
		}
	}

}
